package drill

import (
	"fmt"
	"log"
	"time"
)

// DrillStateDataServer 钻井状态数据服务，集成DAO工具类
type DrillStateDataServer struct {
	dbClient *DrillStateDbClient
}

// NewDrillStateDataServer 创建钻井状态数据服务
func NewDrillStateDataServer(dataDir string) (*DrillStateDataServer, error) {
	dbClient, err := NewDrillStateDbClient(dataDir)
	if err != nil {
		return nil, fmt.Errorf("failed to create drill state database client: %v", err)
	}

	return &DrillStateDataServer{
		dbClient: dbClient,
	}, nil
}

// Close 关闭服务
func (s *DrillStateDataServer) Close() error {
	return s.dbClient.Close()
}

// SaveDrillStateData 保存钻井状态数据
// 时间戳（ct）会自动生成，精确到毫秒
func (s *DrillStateDataServer) SaveDrillStateData(data *DrillStateData) error {
	// 自动生成时间戳（毫秒精度）
	if data.Ct == 0 {
		data.Ct = time.Now().UnixMilli()
	}
	
	// 自动生成数据传输时间字符串
	if data.Dt == "" {
		data.Dt = time.Now().Format("20060102150405")
	}

	if err := s.dbClient.InsertDrillStateData(data); err != nil {
		log.Printf("Failed to save drill state data: %v", err)
		return err
	}
	return nil
}

// QueryByTimeRange 根据时间范围查询数据（方法1）
// startTime和endTime为Unix时间戳（秒）
func (s *DrillStateDataServer) QueryByTimeRange(startTime, endTime int64) ([]*DrillStateData, error) {
	start := time.Unix(startTime, 0)
	end := time.Unix(endTime, 0)
	
	return s.dbClient.QueryByTimeRange(start, end)
}

// QueryRecentSeconds 查询最近n秒的数据（方法2）
func (s *DrillStateDataServer) QueryRecentSeconds(seconds int) ([]*DrillStateData, error) {
	return s.dbClient.QueryRecentSeconds(seconds)
}

// QueryRecentMinutes 查询最近n分钟的数据（方法3）
func (s *DrillStateDataServer) QueryRecentMinutes(minutes int) ([]*DrillStateData, error) {
	return s.dbClient.QueryRecentMinutes(minutes)
}

// QueryRecentDays 查询最近n天的数据（方法4）
func (s *DrillStateDataServer) QueryRecentDays(days int) ([]*DrillStateData, error) {
	return s.dbClient.QueryRecentDays(days)
}

// GetPartitionInfo 获取分区信息
func (s *DrillStateDataServer) GetPartitionInfo() ([]map[string]interface{}, error) {
	partitions, err := s.dbClient.GetPartitions()
	if err != nil {
		return nil, err
	}

	var partitionInfo []map[string]interface{}
	for _, partition := range partitions {
		stats, err := s.dbClient.GetPartitionStats(partition)
		if err != nil {
			log.Printf("Failed to get stats for partition %s: %v", partition, err)
			continue
		}
		
		info := map[string]interface{}{
			"partition":    partition,
			"record_count": stats["record_count"],
			"min_time":     stats["min_time"],
			"max_time":     stats["max_time"],
		}
		partitionInfo = append(partitionInfo, info)
	}

	return partitionInfo, nil
}

// GetDatabaseStats 获取数据库统计信息
func (s *DrillStateDataServer) GetDatabaseStats() (map[string]interface{}, error) {
	partitions, err := s.dbClient.GetPartitions()
	if err != nil {
		return nil, err
	}

	totalRecords := 0
	var minTime, maxTime time.Time
	first := true

	for _, partition := range partitions {
		stats, err := s.dbClient.GetPartitionStats(partition)
		if err != nil {
			continue
		}

		if count, ok := stats["record_count"].(int); ok {
			totalRecords += count
		}

		// 解析时间范围
		if minStr, ok := stats["min_time"].(string); ok {
			if t, err := time.Parse("2006-01-02 15:04:05", minStr); err == nil {
				if first || t.Before(minTime) {
					minTime = t
				}
			}
		}

		if maxStr, ok := stats["max_time"].(string); ok {
			if t, err := time.Parse("2006-01-02 15:04:05", maxStr); err == nil {
				if first || t.After(maxTime) {
					maxTime = t
				}
			}
		}

		first = false
	}

	stats := map[string]interface{}{
		"total_partitions": len(partitions),
		"total_records":    totalRecords,
		"time_range": map[string]string{
			"start": minTime.Format("2006-01-02 15:04:05"),
			"end":   maxTime.Format("2006-01-02 15:04:05"),
		},
		"partitions": partitions,
	}

	return stats, nil
}

// CreateSampleData 创建示例数据（用于测试）
func (s *DrillStateDataServer) CreateSampleData(count int) error {
	now := time.Now()
	
	for i := 0; i < count; i++ {
		// 生成时间戳（毫秒精度）
		timestamp := now.Add(-time.Duration(i) * time.Second)
		ct := timestamp.UnixMilli()
		dt := timestamp.Format("20060102150405")
		
		data := &DrillStateData{
			Ct:          ct,
			Dt:          dt,
			MSETotal:    1500.0 + float64(i%100),
			MSEDownhole: 1200.0 + float64(i%80),
			D:           8.5 + float64(i%10)*0.1,
			R:           4.25 + float64(i%5)*0.05,
			TQsurf:      5000.0 + float64(i%200),
			RPMsurf:     120.0 + float64(i%30),
			ROP:         50.0 + float64(i%20),
			Kn:          0.25 + float64(i%5)*0.01,
			Kt:          9.5 + float64(i%4)*0.1,
			DeltaP:      466.0 + float64(i%2)*119,
			Q:           300.0 + float64(i%50),
			DOC:         0.1 + float64(i%10)*0.01,
			DS:          1000.0 + float64(i%200),
			SSI:         0.5 + float64(i%10)*0.05,
			UCS:         5000.0 + float64(i%1000),
			CreatedAt:   timestamp,
			DataSource:  "sample",
		}
		
		if err := s.SaveDrillStateData(data); err != nil {
			return fmt.Errorf("failed to save sample data %d: %v", i, err)
		}
	}
	
	log.Printf("Created %d sample drill state data records", count)
	return nil
}